﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace daSyntaxAnalyser.SyntaxTree
{
    using daBase.Objects;

    /// <summary>
    /// Элемент синтаксического дерева
    /// </summary>
    public class SyntaxTreeElement : ISyntaxTreeElement
    {
        private static Regex reg = new Regex("\n");
        protected TokenInfo startinfo;
        protected List<TokenInfo> comments;

        /// <summary>
        /// Информация о позиции элемента в коде
        /// </summary>
        public TokenInfo StartInfo { get { return startinfo; } }

        /// <summary>
        /// Комментарии
        /// </summary>
        public List<TokenInfo> Comments { get { return comments; } set { comments = value; } }

        /// <summary>
        /// Добавление отступа в начало каждой строки
        /// </summary>
        /// <param name="Str">исходная строка</param>
        /// <returns>строка с отступом</returns>
        protected static string Tabulate(string Str)
        {
            return string.Format("  {0}", reg.Replace(Str, "\n  "));
        }

        /// <summary>
        /// Получение строкового значения токена
        /// </summary>
        /// <param name="Token">информация о токене</param>
        /// <returns>строка, полученная из токена</returns>
        protected static string TranslateToken(TokenInfo Token)
        {
            switch (Token.Token)
            {
                case DelphiTokens.String:
                    return Token.Text.Substring(1, Token.Text.Length - 2);
                case DelphiTokens.HexConstant:
                    return DChar.AllFromHexCode(Token.Text.Substring(1));
            }
            return string.Empty;
        }

        /// <summary>
        /// Получение строкового значения набора токенов
        /// </summary>
        /// <param name="Tokens">набор токенов</param>
        /// <returns>строка, полученная из токенов</returns>
        public static string TranslateString(List<TokenInfo> Tokens)
        {
            List<string> result = new List<string>();
            result.AddRange(Tokens.ConvertAll<string>(Token => TranslateToken(Token)));
            return result.Join();
        }

        /// <summary>
        /// Нетипизированный энумератор элемента (закрытая реализация интерфейса IEnumerable)
        /// </summary>
        /// <returns>нетипизированный энумератор</returns>
        IEnumerator IEnumerable.GetEnumerator() { yield break; }

        /// <summary>
        /// Создание типизированного энумератора
        /// </summary>
        /// <returns>энумератор</returns>
        protected virtual IEnumerator<ISyntaxTreeElement> CreateEnumerator() { yield break; }

        /// <summary>
        /// Типизированный энумератор элемента (все дочерние элементы)
        /// </summary>
        /// <returns>типизированный энумератор</returns>
        IEnumerator<ISyntaxTreeElement> IEnumerable<ISyntaxTreeElement>.GetEnumerator() { return CreateEnumerator(); }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="StartInfo">информация о позиции элемента в коде</param>
        /// <param name="Comments">комментарии, относящиеся к элементу</param>
        public SyntaxTreeElement(TokenInfo StartInfo, List<TokenInfo> Comments)
        {
            startinfo = StartInfo;
            comments = Comments;
        }

        /// <summary>
        /// Получение комментариев текущего элемента
        /// </summary>
        /// <returns>комментарии</returns>
        protected string CommentsString()
        {
            return ((comments != null) && (comments.Count > 0)) ? string.Format("\r\n{0}\r\n", comments.Join("\r\n")) : string.Empty;
        }
    }
}
